<?php
/**
 * 缓存抽象类
 * 
 * 
 * ============================================================================
 * 版权所有: (c) 2009-2011，<UEShop Inc>，并保留所有权利。
 * 网站地址: http://www.ueshop.cn
 * ----------------------------------------------------------------------------
 * 这不是一个自由软件！您只能在不用于商业目的的前提下对程序代码进行修改和使用；
 * 不允许对程序代码以任何形式任何目的的再发布。
 * ============================================================================
 * @author cmpan
 * @copyright   Copyright (c) 2009-2011 UEShop Inc. (http://www.ueshop.cn)
 * @license     http://www.ueshop.cn/1_0.txt
 */
class UE_Cache_Exception extends UE_Exception {}

abstract class UE_Cache_Abstract {
	/**
	 * 读缓存变量
	 *
	 * @param string $key 缓存下标
	 * @return mixed
	 */
    abstract public function fetch($key);
	
	/**
	 * 缓存变量
	 *
	 * @param string $key 缓存变量下标
	 * @param string $value 缓存变量的值
	 * @return bool
	 */
    abstract public function store($key, $value);
	
	/**
	 * 删除缓存变量
	 *
	 * @param string $key 缓存下标
	 * @return UE_Cache_Abstract
	 */
    abstract public function delete($key);
	
	/**
	 * 清(删)除所有缓存
	 *
	 * @param string $dir 某个目录
	 * @return UE_Cache_Abstract
	 */
    abstract public function clear($dir = '');
	
	/**
	 * 锁定缓存变量
	 *
	 * @param string $key 缓存下标
	 * @return UE_Cache_Abstract
	 */
    abstract public function lock($key);

	/**
	 * 缓存变量解锁
	 *
	 * @param string $key 缓存下标
	 * @return UE_Cache_Abstract
	 */
    abstract public function unlock($key);

	/**
	 * 取得缓存变量是否被锁定
	 *
	 * @param string $key 缓存下标
	 * @return bool
	 */
    abstract public function isLocked($key);

	/**
	 * 确保不是锁定状态
	 * 最多做$tries次睡眠等待解锁，超时则跳过并解锁
	 *
	 * @param string $key 缓存下标
	 */
    public function checkLock($key) {
    	if (!$this->isLocked($key)) {
    		return $this;
    	}
    	
        $tries = 10;
        $count = 0;
        do {
            usleep(200);
            $count ++;
        } while ($count <= $tries && $this->isLocked($key));  // 最多做十次睡眠等待解锁，超时则跳过并解锁

        $this->isLocked($key) && $this->unlock($key);
        
        return $this;
    }
}